package com.betting.service;

import com.betting.entity.BetRecord;
import com.betting.dto.StreakDetail;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class ExportService {
    
    private final BetRecordService betRecordService;
    
    public byte[] exportToExcel(List<BetRecord> records) throws Exception {
        try (Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet("投注记录");
            
            // 创建标题行
            Row headerRow = sheet.createRow(0);
            String[] headers = {"时间", "类型", "盘口", "水位", "投注金额", "结果金额", "是否获胜", "备注"};
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
            }
            
            // 填充数据
            int rowNum = 1;
            for (BetRecord record : records) {
                Row row = sheet.createRow(rowNum++);
                row.createCell(0).setCellValue(record.getBetTime().toString());
                row.createCell(1).setCellValue(record.getBetType());
                row.createCell(2).setCellValue(record.getHandicapValue().toString());
                row.createCell(3).setCellValue(record.getOdds().toString());
                row.createCell(4).setCellValue(record.getBetAmount().toString());
                row.createCell(5).setCellValue(record.getResultAmount().toString());
                row.createCell(6).setCellValue(record.getBetResult() != null ? record.getBetResult().toString() : "");
                row.createCell(7).setCellValue(record.getNote());
            }
            
            // 自动调整列宽
            for (int i = 0; i < headers.length; i++) {
                sheet.autoSizeColumn(i);
            }
            
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            workbook.write(outputStream);
            return outputStream.toByteArray();
        }
    }

    public byte[] exportStreakToExcel(Map<String, Object> stats) {
        if (stats == null || !stats.containsKey("streakDetails")) {
            throw new RuntimeException("统计数据为空或格式不正确");
        }

        try (XSSFWorkbook workbook = new XSSFWorkbook()) {
            // ================= 样式定义 =================
            XSSFCellStyle headerStyle = createHeaderStyle(workbook);
            XSSFCellStyle dataStyle = createDataStyle(workbook);
            XSSFCellStyle amountStyle = createAmountStyle(workbook);
            XSSFCellStyle winStyle = createStatusStyle(workbook, new byte[]{(byte)239, (byte)68, (byte)68}); // 红色
            XSSFCellStyle loseStyle = createStatusStyle(workbook, new byte[]{(byte)16, (byte)185, (byte)129}); // 绿色
            XSSFCellStyle drawStyle = createStatusStyle(workbook, new byte[]{(byte)245, (byte)158, (byte)11}); // 橙色

            // ================= 创建Sheet和表头 =================
            Sheet sheet = workbook.createSheet("连胜连败记录");
            setColumnWidths(sheet);
            createHeaderRow(sheet, headerStyle);

            // ================= 填充数据 =================
            List<StreakDetail> details = (List<StreakDetail>) stats.get("streakDetails");
            int rowNum = 1;
            
            if (details != null) {
                for (StreakDetail detail : details) {
                    Row row = sheet.createRow(rowNum++);
                    fillDataRow(row, detail, dataStyle, amountStyle, winStyle, loseStyle, drawStyle);
                }
            }

            // ================= 添加汇总行 =================
            // 添加最高连胜、最高连败和命中率信息
            Row summaryRow = sheet.createRow(rowNum++);
            createMergedCell(summaryRow, 0, 3, "统计信息", headerStyle);
            
            // 最高连胜
            createCell(summaryRow, 4, "最高连胜", dataStyle);
            createCell(summaryRow, 5, String.valueOf(stats.get("maxWinStreak")), winStyle);
            
            // 最高连败
            createCell(summaryRow, 6, "最高连败", dataStyle);
            createCell(summaryRow, 7, String.valueOf(stats.get("maxLoseStreak")), loseStyle);
            
            // 命中率
            Row hitRateRow = sheet.createRow(rowNum++);
            createMergedCell(hitRateRow, 0, 3, "", headerStyle);
            createCell(hitRateRow, 4, "命中率", dataStyle);
            createCell(hitRateRow, 5, String.format("%.2f%%", (Double)stats.get("hitRate")), 
                (Double)stats.get("hitRate") >= 50 ? winStyle : loseStyle);
            
            // 自动调整列宽
            for (int i = 0; i < 8; i++) {
                sheet.autoSizeColumn(i);
            }
            
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            workbook.write(outputStream);
            return outputStream.toByteArray();
        } catch (Exception e) {
            throw new RuntimeException("生成Excel失败: " + e.getMessage(), e);
        }
    }

    private XSSFCellStyle createHeaderStyle(XSSFWorkbook workbook) {
        XSSFCellStyle style = workbook.createCellStyle();
        XSSFFont font = workbook.createFont();
        font.setBold(true);
        font.setColor(new XSSFColor(new byte[]{(byte)255, (byte)255, (byte)255}, null));
        style.setFont(font);
        style.setFillForegroundColor(new XSSFColor(new byte[]{(byte)51, (byte)102, (byte)153}, null));
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        style.setAlignment(HorizontalAlignment.CENTER);
        setBorders(style);
        return style;
    }

    private XSSFCellStyle createDataStyle(XSSFWorkbook workbook) {
        XSSFCellStyle style = workbook.createCellStyle();
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        setBorders(style);
        return style;
    }

    private XSSFCellStyle createAmountStyle(XSSFWorkbook workbook) {
        XSSFCellStyle style = workbook.createCellStyle();
        style.setAlignment(HorizontalAlignment.RIGHT);
        style.setDataFormat(workbook.createDataFormat().getFormat("¥#,##0.00"));
        setBorders(style);
        return style;
    }

    private void setBorders(CellStyle style) {
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
    }

    private void setColumnWidths(Sheet sheet) {
        sheet.setColumnWidth(0, 4500);  // 时间列宽
        sheet.setColumnWidth(1, 8000);  // 比赛列宽
        sheet.setColumnWidth(4, 3000);  // 结果列宽
        sheet.setColumnWidth(5, 4000);  // 金额列宽
        sheet.setColumnWidth(6, 3500);  // 连胜/负列宽
        sheet.setColumnWidth(7, 4500);  // 总结算金额列宽
    }

    private void createHeaderRow(Sheet sheet, CellStyle headerStyle) {
        Row headerRow = sheet.createRow(0);
        String[] headers = {"时间", "比赛", "玩法", "盘口", "水位", "结果", "金额", "连胜/负", "总结算金额"};
        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
            cell.setCellStyle(headerStyle);
        }
    }

    private void fillDataRow(Row row, StreakDetail detail, CellStyle dataStyle, 
                           CellStyle amountStyle, CellStyle winStyle, CellStyle loseStyle, CellStyle drawStyle) {
        // 时间
        createCell(row, 0, detail.getBetTime().format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), dataStyle);
        
        // 比赛
        createCell(row, 1, detail.getMatch(), dataStyle);
        
        // 玩法
        createCell(row, 2, detail.getBetType(), dataStyle);
        
        // 盘口
        String handicapStr = "";
        if (detail.getHandicapText() != null) {
            // 如果有文字形式的盘口值，直接使用
            handicapStr = detail.getHandicapText();
        } else {
            // 否则使用数字形式
            Double handicapValue = detail.getHandicapValue();
            if (handicapValue != null) {
                // 如果是整数，去掉小数部分
                if (handicapValue == Math.floor(handicapValue)) {
                    handicapStr = String.format("%.0f", handicapValue);
                } else {
                    java.text.DecimalFormat df = new java.text.DecimalFormat("#.##");
                    df.setDecimalSeparatorAlwaysShown(false);
                    handicapStr = df.format(handicapValue);
                }
            }
        }
        createCell(row, 3, handicapStr, dataStyle);
        
        // 水位
        Double odds = detail.getOdds();
        String oddsStr = "";
        if (odds != null) {
            java.text.DecimalFormat df = new java.text.DecimalFormat("#.##");
            df.setDecimalSeparatorAlwaysShown(false);
            oddsStr = df.format(odds);
        }
        createCell(row, 4, oddsStr, dataStyle);
        
        // 结果
        String result = detail.getBetResult();
        Cell resultCell = row.createCell(5);
        resultCell.setCellValue(result);
        resultCell.setCellStyle(getResultStyle(result, winStyle, loseStyle, drawStyle));
        
        // 金额
        double amount = detail.getResultAmount();
        createAmountCell(row, 6, amount, amountStyle);
        
        // 连胜/负
        String streak = String.valueOf(detail.getStreak());
        Cell streakCell = row.createCell(7);
        streakCell.setCellValue(formatStreak(streak));
        streakCell.setCellStyle(getStreakStyle(streak, winStyle, loseStyle, drawStyle));
        
        // 总结算金额
        double totalAmount = detail.getTotalResultAmount();
        createAmountCell(row, 8, totalAmount, amountStyle);
    }

    private String getStringValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        return value != null ? value.toString() : "";
    }

    private double getDoubleValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) return 0.0;
        if (value instanceof Number) {
            return ((Number) value).doubleValue();
        }
        try {
            return Double.parseDouble(value.toString());
        } catch (NumberFormatException e) {
            return 0.0;
        }
    }

    private String formatBetType(String betType, String handicapTeam, String homeTeam, String awayTeam) {
        if (betType == null) return "";
        if (!"让球".equals(betType)) return betType;
        
        if ("HOME".equals(handicapTeam) && homeTeam != null) {
            return homeTeam + "-让球";
        } else if ("AWAY".equals(handicapTeam) && awayTeam != null) {
            return awayTeam + "-让球";
        }
        return betType;
    }

    private void createAmountCell(Row row, int column, double value, CellStyle style) {
        Cell cell = row.createCell(column);
        cell.setCellValue(value);
        cell.setCellStyle(style);
    }

    private void createSummaryRow(Sheet sheet, int rowNum, Map<String, Object> stats, 
                                CellStyle headerStyle, CellStyle dataStyle, CellStyle amountStyle) {
        Row summaryRow = sheet.createRow(rowNum);
        createMergedCell(summaryRow, 0, 3, "汇总统计：", headerStyle);
        createCell(summaryRow, 4, "最高连胜:", dataStyle);
        createCell(summaryRow, 5, getStringValue(stats, "maxWinStreak"), amountStyle);
        createCell(summaryRow, 6, "最高连败:", dataStyle);
        createCell(summaryRow, 7, getStringValue(stats, "maxLoseStreak"), amountStyle);
    }

    private XSSFCellStyle createStatusStyle(XSSFWorkbook workbook, byte[] rgb) {
        XSSFCellStyle style = workbook.createCellStyle();
        style.setFillForegroundColor(new XSSFColor(rgb, new DefaultIndexedColorMap()));
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        style.setFont(workbook.createFont());
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        return style;
    }

    private void createCell(Row row, int column, String value, CellStyle style) {
        Cell cell = row.createCell(column);
        cell.setCellValue(value);
        cell.setCellStyle(style);
    }

    private void createMergedCell(Row row, int firstCol, int lastCol, String value, CellStyle style) {
        Cell cell = row.createCell(firstCol);
        cell.setCellValue(value);
        cell.setCellStyle(style);
        row.getSheet().addMergedRegion(new CellRangeAddress(row.getRowNum(), row.getRowNum(), firstCol, lastCol));
    }

    private CellStyle getResultStyle(String result, CellStyle winStyle, CellStyle loseStyle, CellStyle drawStyle) {
        if (result.contains("WIN")) return winStyle;
        if (result.contains("LOSE")) return loseStyle;
        return drawStyle;
    }

    private String formatStreak(String streak) {
        if (streak.equals("和")) return streak;
        if (streak.startsWith("+")) return streak.substring(1) + "连胜";
        if (streak.startsWith("-")) return streak.substring(1) + "连败";
        return streak;
    }

    private CellStyle getStreakStyle(String streak, CellStyle winStyle, CellStyle loseStyle, CellStyle drawStyle) {
        if (streak.equals("和")) return drawStyle;
        if (streak.startsWith("+")) return winStyle;
        if (streak.startsWith("-")) return loseStyle;
        return drawStyle;
    }

    public byte[] exportDailyToExcel(Map<String, Object> stats) {
        try (XSSFWorkbook workbook = new XSSFWorkbook()) {
            XSSFSheet sheet = workbook.createSheet("每日统计");
            
            // 设置列宽
            sheet.setColumnWidth(0, 4000);  // 日期
            sheet.setColumnWidth(1, 3000);  // 投注笔数
            sheet.setColumnWidth(2, 4000);  // 投注金额
            sheet.setColumnWidth(3, 4000);  // 结算金额
            sheet.setColumnWidth(4, 3000);  // 盈亏
            sheet.setColumnWidth(5, 3000);  // 胜率
            
            // 创建标题样式
            XSSFCellStyle headerStyle = workbook.createCellStyle();
            headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
            headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            headerStyle.setAlignment(HorizontalAlignment.CENTER);
            headerStyle.setBorderBottom(BorderStyle.THIN);
            
            // 创建数据样式
            XSSFCellStyle dataStyle = workbook.createCellStyle();
            dataStyle.setAlignment(HorizontalAlignment.CENTER);
            dataStyle.setBorderBottom(BorderStyle.THIN);
            
            // 创建金额样式
            XSSFCellStyle amountStyle = workbook.createCellStyle();
            amountStyle.setAlignment(HorizontalAlignment.RIGHT);
            amountStyle.setDataFormat(workbook.createDataFormat().getFormat("¥#,##0.00"));
            amountStyle.setBorderBottom(BorderStyle.THIN);
            
            // 创建百分比样式
            XSSFCellStyle percentStyle = workbook.createCellStyle();
            percentStyle.setAlignment(HorizontalAlignment.CENTER);
            percentStyle.setDataFormat(workbook.createDataFormat().getFormat("0.00%"));
            percentStyle.setBorderBottom(BorderStyle.THIN);
            
            // 创建表头
            Row headerRow = sheet.createRow(0);
            String[] headers = {"日期", "投注笔数", "投注金额", "结算金额", "盈亏", "胜率"};
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
            }
            
            // 填充数据
            List<Map<String, Object>> dailyStats = (List<Map<String, Object>>) stats.get("dailyStats");
            int rowNum = 1;
            for (Map<String, Object> daily : dailyStats) {
                Row row = sheet.createRow(rowNum++);
                
                // 日期
                Cell dateCell = row.createCell(0);
                dateCell.setCellValue(daily.get("date").toString());
                dateCell.setCellStyle(dataStyle);
                
                // 投注笔数
                Cell countCell = row.createCell(1);
                countCell.setCellValue(((Number) daily.get("betCount")).intValue());
                countCell.setCellStyle(dataStyle);
                
                // 投注金额
                Cell betAmountCell = row.createCell(2);
                betAmountCell.setCellValue(((Number) daily.get("betAmount")).doubleValue());
                betAmountCell.setCellStyle(amountStyle);
                
                // 结算金额
                Cell settleAmountCell = row.createCell(3);
                settleAmountCell.setCellValue(((Number) daily.get("settleAmount")).doubleValue());
                settleAmountCell.setCellStyle(amountStyle);
                
                // 盈亏
                Cell profitCell = row.createCell(4);
                profitCell.setCellValue(((Number) daily.get("profit")).doubleValue());
                profitCell.setCellStyle(amountStyle);
                
                // 胜率
                Cell winRateCell = row.createCell(5);
                winRateCell.setCellValue(((Number) daily.get("winRate")).doubleValue() / 100);
                winRateCell.setCellStyle(percentStyle);
            }
            
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            workbook.write(outputStream);
            return outputStream.toByteArray();
            
        } catch (Exception e) {
            throw new RuntimeException("生成每日统计Excel失败", e);
        }
    }

    public byte[] exportMonthlyToExcel(Map<String, Object> stats) {
        try (XSSFWorkbook workbook = new XSSFWorkbook()) {
            XSSFSheet sheet = workbook.createSheet("月度统计");
            
            // 设置列宽
            sheet.setColumnWidth(0, 4000);  // 月份
            sheet.setColumnWidth(1, 3000);  // 投注笔数
            sheet.setColumnWidth(2, 4000);  // 投注金额
            sheet.setColumnWidth(3, 4000);  // 结算金额
            sheet.setColumnWidth(4, 3000);  // 盈亏
            sheet.setColumnWidth(5, 3000);  // 胜率
            sheet.setColumnWidth(6, 3000);  // 最高连胜
            sheet.setColumnWidth(7, 3000);  // 最高连败
            
            // 创建标题样式
            XSSFCellStyle headerStyle = workbook.createCellStyle();
            headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
            headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            headerStyle.setAlignment(HorizontalAlignment.CENTER);
            headerStyle.setBorderBottom(BorderStyle.THIN);
            
            // 创建数据样式
            XSSFCellStyle dataStyle = workbook.createCellStyle();
            dataStyle.setAlignment(HorizontalAlignment.CENTER);
            dataStyle.setBorderBottom(BorderStyle.THIN);
            
            // 创建金额样式
            XSSFCellStyle amountStyle = workbook.createCellStyle();
            amountStyle.setAlignment(HorizontalAlignment.RIGHT);
            amountStyle.setDataFormat(workbook.createDataFormat().getFormat("¥#,##0.00"));
            amountStyle.setBorderBottom(BorderStyle.THIN);
            
            // 创建百分比样式
            XSSFCellStyle percentStyle = workbook.createCellStyle();
            percentStyle.setAlignment(HorizontalAlignment.CENTER);
            percentStyle.setDataFormat(workbook.createDataFormat().getFormat("0.00%"));
            percentStyle.setBorderBottom(BorderStyle.THIN);
            
            // 创建表头
            Row headerRow = sheet.createRow(0);
            String[] headers = {"月份", "投注笔数", "投注金额", "结算金额", "盈亏", "胜率", "最高连胜", "最高连败"};
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
            }
            
            // 填充数据
            List<Map<String, Object>> monthlyStats = (List<Map<String, Object>>) stats.get("monthlyStats");
            int rowNum = 1;
            for (Map<String, Object> monthly : monthlyStats) {
                Row row = sheet.createRow(rowNum++);
                
                // 月份
                Cell monthCell = row.createCell(0);
                monthCell.setCellValue(monthly.get("month").toString());
                monthCell.setCellStyle(dataStyle);
                
                // 投注笔数
                Cell countCell = row.createCell(1);
                countCell.setCellValue(((Number) monthly.get("betCount")).intValue());
                countCell.setCellStyle(dataStyle);
                
                // 投注金额
                Cell betAmountCell = row.createCell(2);
                betAmountCell.setCellValue(((Number) monthly.get("betAmount")).doubleValue());
                betAmountCell.setCellStyle(amountStyle);
                
                // 结算金额
                Cell settleAmountCell = row.createCell(3);
                settleAmountCell.setCellValue(((Number) monthly.get("settleAmount")).doubleValue());
                settleAmountCell.setCellStyle(amountStyle);
                
                // 盈亏
                Cell profitCell = row.createCell(4);
                profitCell.setCellValue(((Number) monthly.get("profit")).doubleValue());
                profitCell.setCellStyle(amountStyle);
                
                // 胜率
                Cell winRateCell = row.createCell(5);
                winRateCell.setCellValue(((Number) monthly.get("winRate")).doubleValue() / 100);
                winRateCell.setCellStyle(percentStyle);
                
                // 最高连胜
                Cell maxWinStreakCell = row.createCell(6);
                maxWinStreakCell.setCellValue(((Number) monthly.get("maxWinStreak")).intValue());
                maxWinStreakCell.setCellStyle(dataStyle);
                
                // 最高连败
                Cell maxLoseStreakCell = row.createCell(7);
                maxLoseStreakCell.setCellValue(((Number) monthly.get("maxLoseStreak")).intValue());
                maxLoseStreakCell.setCellStyle(dataStyle);
            }
            
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            workbook.write(outputStream);
            return outputStream.toByteArray();
            
        } catch (Exception e) {
            throw new RuntimeException("生成月度统计Excel失败", e);
        }
    }
} 